package com.dh.convert.rule.function;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import org.apache.commons.lang3.time.DateFormatUtils;
import com.alibaba.fastjson.util.TypeUtils;
import com.dh.convert.exception.ConvertValueException;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorNil;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorString;

/**
 * 
 * 类AddMonthFunction.java的实现描述：日期月份增减函数并格式化
 * 
 * @author chenwenjing001 2018年11月21日 下午3:42:00
 */
public class AddDateFunction extends AbstractFunction {

	@Override
	public String getName() {
		return "addDate";
	}

	@Override
	public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3,
			AviatorObject arg4) {
		Object date = arg1.getValue(env);
		if(date==null)
			return AviatorNil.NIL;
		String dateString =(String) date;
		int num = TypeUtils.castToInt(arg2.getValue(env));
		String formatter = FunctionUtils.getStringValue(arg3, env);
		DateTypeEnum dateType = DateTypeEnum.valueOf(FunctionUtils.getStringValue(arg4, env));
		Integer calendarField = null;
		switch (dateType) {
		case D:
			calendarField = Calendar.DAY_OF_MONTH;
			break;
		case H:
			calendarField = Calendar.HOUR_OF_DAY;
			break;
		case M:
			calendarField = Calendar.MONTH;
			break;
		case Y:
			calendarField = Calendar.MONTH;
			break;
		case m:
			calendarField = Calendar.MINUTE;
			break;
		case S:
			calendarField = Calendar.SECOND;
			break;
		case MS:
			calendarField = Calendar.MILLISECOND;
			break;
		default:
			break;
		}
		Date addMonthDate =null;
		try {
			addMonthDate = add(parse(dateString,formatter), calendarField ,num);
		} catch (ParseException e) {
			throw new ConvertValueException("date parse error",e);
		}
		return new AviatorString(DateFormatUtils.format(addMonthDate, formatter));
	}

	private Date add(Date date, int calendarField, int amount) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		}
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(calendarField, amount);
		return c.getTime();
	}

	  public static Date parse(String strDate,String formatter) throws ParseException  
	    {  
	        return new SimpleDateFormat(formatter).parse(strDate);    
	    }  
    
	enum DateTypeEnum {
		Y, M, D, H, m, S, MS;
	}
}
